(function ($) {
  Drupal.behaviors.contextExtendEditor = {
    attach: function(context, settings) {
      $('.context-extend-edit-context').click(function(e){
        $('.context-extend-edit-context').hide(200);
        contextBlockEditor[id].editStart($('#context-extend-ui-editor'), defaultContext);
        $('#context-extend-disabled-blocks').removeClass('element-invisible').dialog({
          title: Drupal.t('Add block'),
          position: ['center','center'],
          close: function( event, ui ) {
            $('.context-extend-edit-context').show();
            if (getUrlVariable('drag-drop') != 1) {
              contextBlockEditor[id].editFinish();
            }
          },
          width: '500px'
        }).parent().css({position:'fixed'});
        e.preventDefault();
        return false;
      });

      var defaultContext = Drupal.settings.context_extend.current_context;
      var id = 'context-extend-ui-editor';
      var editor = $('#context-extend-ui-editor');

      var contextBlockEditor = contextBlockEditor || {};
      contextBlockEditor[id] = new DrupalContextExtendBlockEditor($('#context-extend-ui-editor'));
      if (getUrlVariable('drag-drop') == 1) {
        contextBlockEditor[id].editStart($('#context-extend-ui-editor'), defaultContext);
      }

      if ($('#dialog-update-ipe').length == 0) {
        var str_html = '<div id="dialog-update-ipe">';
        str_html += '<span class="question-string">'  + Drupal.t('Update changed contents?') + '</span>';
        str_html += '<span class="question confirm">' + Drupal.t('Update') + '</span>';
        str_html += '<span class="question cancel">' + Drupal.t('Cancel') + '</span></div>';
        $('.region-page-bottom').prepend($(str_html));
        $('#dialog-update-ipe').hide();
      }

    },
    detach: function() {
    }
  };
  var getUrlVariable = function(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
      var sParameterName = sURLVariables[i].split('=');
      if (sParameterName[0] == sParam) {
        return sParameterName[1];
      }
    }
    return false;
  }
})(jQuery);

(function($){
  /**
   * Context block editor. AHAH editor for live block reaction editing.
   */
  DrupalContextExtendBlockEditor = function(editor) {
    this.editor = editor;
    this.state = {};
    this.blocks = {};
    this.regions = {};
    this.isUpdate = true;

    return this;
  };

  DrupalContextExtendBlockEditor.prototype = {
    initBlocks : function(blocks) {
      var self = this;
      this.blocks = blocks;
      blocks.each(function() {
        if($(this).hasClass('context-block-empty')) {
          $(this).removeClass('context-block-hidden');
        }
        $(this).addClass('draggable');
        if ($(this).find('a.context-block-handle').length == 0) {
          $(this).prepend($('<a class="context-block-handle"></a>'));
          $(this).prepend($('<a class="context-block-remove"></a>').click(function() {
            $(this).parent ('.block').eq(0).fadeOut('medium', function() {
              var context = $(this).find('a.context-block').attr('class').split('edit-')[1].split(' ')[0];
              self.showConfirmDialog(Drupal.t('Do you want to Save these changes?'), context);
              $(this).prependTo('#disabled-blocks .disabled-blocks').show();
            });
            return false;
          }));
        }
      });
    },
    initRegions : function(regions) {
      this.regions = regions;
    },
    // Update Server to match the current block states.
    updateBlocks : function(context) {
      var self = this;
      // Let the server know what the new block order is.
      $.post(Drupal.settings.context_extend.updatePath,
        {
          'form_token': Drupal.settings.context_extend.formToken,
          'regions': JSON.stringify(self.getState()),
          'context': context
        },
        function (data) {
          if (data.length != 0) {
            result = JSON.parse(data);
            if (result.success == true) {
              $('#dialog-update-ipe:not(.showed)').show('fast', function(){
                $('.confirm', this).hide();
                $('.question-string').html(Drupal.t('Your changes are saved'));
                $('.cancel', this).html(Drupal.t('Ok'));
                $('.cancel', this).click(function() {
                  $('#dialog-update-ipe').hide(300).removeClass('showed');
                  $('#dialog-update-ipe .confirm').show();
                  $('#dialog-update-ipe .cancel').html(Drupal.t('Cancel'));
                  $('#dialog-update-ipe .question-string').html(Drupal.t('Update changed contents?'));
                });
              }).addClass('showed').hide(2000, function() {
                  $('#dialog-update-ipe').removeClass('showed');
                  $('#dialog-update-ipe .confirm').show();
                  $('#dialog-update-ipe .cancel').html(Drupal.t('Cancel'));
                  $('#dialog-update-ipe .question-string').html(Drupal.t('Update changed contents?'));
                });
            }
          }
        }
      );
      self.isUpdate = true;
    },
    /**
     * Sets up the drag-and-drop behavior and the 'close' button.
     */
    setupDrawer: function (editor, context) {
      var self = this;
      // Initialize drag-and-drop.
      var regions = $('div.region');
      regions.sortable({
        forcePlaceholderSize: true,
        revert: true,
        cursor: 'move',
        cursorAt: {left: 0, top:0},
        dropOnEmpty: true,
        items: '> div.block, > div.disabled-block',
        handle: 'a.context-block-handle',
        placeholder: 'block-placeholder clearfix',
        tolerance: 'pointer',
        start: function(event, ui) {/*self.startDrawer(event, ui)*/},
        over: function(event, ui) {/*self.overDrawer(event, ui)*/},
        sort: function(event, ui) {/*self.sortDrawer(event, ui)*/},
        update: function(event, ui) {self.updateDrawer(event, ui, editor, context)}
      });
      // Second pass, hook up all regions via connectWith to each other.
      $(regions).each(function() {
        $(this).sortable('option', 'connectWith', ['.ui-sortable']);
      });
    },
    /**
     * Sends block order to the server, and expand previously disabled blocks.
     *
     * This function is called on the jQuery UI Sortable "update" event.
     *
     * @param event
     *   The event that triggered this callback.
     * @param ui
     *   An object containing information about the item that was just dropped.
     */
    updateDrawer: function (event, ui, editor, context) {
      var self = this;
      var item = $(ui.item);
      // If the user dragged a disabled block, load the block contents.
      if (item.hasClass('disabled-block')) {
        var module, delta, itemClass;
        itemClass = item.attr('class');
        // Determine the block module and delta.
        module = itemClass.match(/\bmodule-(\S+)\b/)[1];
        delta = itemClass.match(/\bdelta-(\S+)\b/)[1];

        // Load the newly enabled block's content.
        $.get(Drupal.settings.context_extend.blockContent + '/' + module + '/' + delta + '/' + context, {'context': context},
          function (block) {
            var newBlock = $(block);
            if (newBlock) {
              item.replaceWith(newBlock);
              self.initBlocks(newBlock);
            }

            if (item.find('div.content').is(':empty')) {
              item.find('div.content').html(Drupal.settings.context_extend.emptyBlockText);
            }
            Drupal.attachBehaviors(item);
          },
          'html'
        );
      }

      self.updateEditorFieldState();
      self.showConfirmDialog(Drupal.t('Do you want to Save these changes?'), context);
    },
    // Start editing. Attach handlers, begin draggable/sortables.
    editStart : function(editor, context) {
      var self = this;
      // This is redundant to the start handler found in context_ui.js.
      // However it's necessary that we trigger this class addition before
      // we call .sortable() as the empty regions need to be visible.
      $('.block:not(.draggable)').each(function() {
        $(this).addClass('draggable');
        if ($(this).find('a.context-block').length == 0) {
          itemClass = $(this).attr('class');
          // Determine the block module and delta.
          module = itemClass.match(/\bmodule-(\S+)\b/)[1];
          delta = itemClass.match(/\bdelta-(\S+)\b/)[1];
          $(this).find('div.content').prepend('<a class="context-block editable edit-' + context + '" id="context-block-' + module + '-' + delta + '"></a>')
        }
      });
      this.disableTextSelect();
      this.initBlocks($('.block:has(a.context-block)'));
      this.initRegions($('.context-block-region').parent());

      self.setupDrawer(editor, context);
    },
    // Finish editing. Remove handlers.
    editFinish : function() {
      this.enableTextSelect();

      this.regions.sortable('destroy');

      this.updateEditorFieldState();

      // Unhack the user agent.
      if ($.ui.version === '1.6' && $.browser.safari) {
        $.browser.mozilla = false;
      }
      $('.placeholder').remove();
    },
    // Update form hidden field with JSON representation of current block visibility states.
    updateEditorFieldState : function() {
      var self = this;
      self.getState();
      // Serialize here and set form element value.
      $('input.context-block-editor-state', this.editor).val(JSON.stringify(this.state));
    },
    // Get state of all regions
    getState: function () {
      var self = this;
      var regions = $('.context-block-region').parent();
      $(regions).each(function() {
        var region = $('.context-block-region', this).attr('id').split('context-block-region-')[1];
        var blocks = [];
        $('a.context-block', $(this)).each(function() {
          if ($(this).attr('class').indexOf('edit-') != -1) {
            var bid = $(this).attr('id').split('context-block-')[1];
            var context = $(this).attr('class').split('edit-')[1].split(' ')[0];
            context = context ? context : 0;
            var block = {'bid': bid, 'context': context};
            blocks.push(block);
          }
        });
        self.state[region] = blocks;
      });
      return self.state;
    },
    //Disable text selection.
    disableTextSelect : function() {
      if ($.browser.safari) {
        $('.block:has(a.context-block):not(:has(input,textarea))').css('WebkitUserSelect','none');
      }
      else if ($.browser.mozilla) {
        $('.block:has(a.context-block):not(:has(input,textarea))').css('MozUserSelect','none');
      }
      else if ($.browser.msie) {
        $('.block:has(a.context-block):not(:has(input,textarea))').bind('selectstart.contextBlockEditor', function() { return false; });
      }
      else {
        $(this).bind('mousedown.contextBlockEditor', function() { return false; });
      }
    },
    //Enable text selection.
    enableTextSelect : function() {
      if ($.browser.safari) {
        $('*').css('WebkitUserSelect','');
      }
      else if ($.browser.mozilla) {
        $('*').css('MozUserSelect','');
      }
      else if ($.browser.msie) {
        $('*').unbind('selectstart.contextBlockEditor');
      }
      else {
        $(this).unbind('mousedown.contextBlockEditor');
      }
    },
    // Show confirm dialog after darg/drop and leave page
    showConfirmDialog : function(question, context) {
      var self = this;
      self.isUpdate = false;
      $('#dialog-update-ipe:not(.showed)').show('fast', function(){

        $('.confirm', this).click(function() {
          self.updateBlocks(context);
          $('#dialog-update-ipe').hide(300).removeClass('showed');
        });

        $('.cancel', this).click(function() {
          $('#dialog-update-ipe').hide(300).removeClass('showed');
        });
      }).addClass('showed');
    }
  }; //End of DrupalContextExtendBlockEditor prototype

})(jQuery);
